home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / boot / czesc_1 / beep / beep.c < prev    next >
C/C++ Source or Header  |  1992-01-18  |  4KB  |  225 lines

  1. /*
  2.  * beep.c - adds a sampled sound to DisplayBeep()
  3.  *
  4.  * Bruno Costa - 19 Feb 91 - 19 Feb 91
  5.  *
  6.  * NOTE:
  7.  *   This program is VERY sensitive to compiler environment.
  8.  *  Compile under Lattice 5.1 with options -r0 -y -v.
  9.  */
  10.  
  11. /*
  12.  * TODO: add option to remove screen flash
  13.  */
  14.  
  15. #include <exec/types.h>
  16. #include <intuition/intuition.h>
  17. #include <graphics/gfxmacros.h>
  18. #include <proto/exec.h>
  19. #include <proto/dos.h>
  20. #include <proto/intuition.h>
  21.  
  22. #include "intuition.lvo"
  23.  
  24. #define MAX(a,b) (((a)>(b))?(a):(b))
  25. #define MIN(a,b) (((a)<(b))?(a):(b))
  26.  
  27. #define PORTNAME "beep.port"
  28. #define INVALID (-1)
  29.  
  30. #if DETACH
  31. long _stack = 3000;
  32. char *_procname = "BeepHandler";
  33. long _priority = 2;
  34. long _BackGroundIO = 1;
  35. extern BPTR _Backstdout;
  36. #else
  37. BPTR _Backstdout;
  38. #endif
  39.  
  40. /*
  41.  * Resident Amiga libraries
  42.  */
  43. struct Library *IntuitionBase;
  44.  
  45. /*
  46.  * CLI Messages
  47.  */
  48. #define BANNER   "\x1b[33mBeep 1.0\x1b[31m - \xa9 1991 by Bruno Costa\n"
  49. #define USAGE    "usage: \x1b[1mBeep\x1b[0m [-q | <soundfile>]\n"
  50. #define REMOVING "\x1b[1mBeep:\x1b[0m handler removed.\n"
  51. #define NOTLOAD  "\x1b[1mBeep:\x1b[0m could not load desired sound.\n"
  52.  
  53. /*
  54.  * pointer to old system functions
  55.  */
  56. typedef void (* __asm BeepFunc) (register __a0 struct Screen *scr,
  57.                                  register __a6 struct Library *ibase);
  58.  
  59. static BeepFunc oldbeep;
  60.  
  61. /*
  62.  * Data shared by handler and interposed function
  63.  */
  64. static struct Task *handler = NULL;
  65. ULONG beepsig = 0;
  66. int flash = TRUE;
  67.  
  68. /*
  69.  * C routine to be interposed
  70.  */
  71. void __asm mybeep (register __a0 struct Screen *scr,
  72.                    register __a6 struct Library *ibase)
  73. {
  74.  Signal (handler, 1L << beepsig);
  75.  if (flash)
  76.    (*oldbeep) (scr,ibase);
  77. }
  78.  
  79.  
  80. /*
  81.  * message port
  82.  */
  83. static struct MsgPort myport;
  84.  
  85.  
  86. void usage (void)    /* dead end */
  87. {
  88.  Write (_Backstdout, USAGE, sizeof(USAGE));
  89. #if DETACH
  90.  Close (_Backstdout);
  91. #endif
  92.  exit (5);
  93. }
  94.  
  95.  
  96. void main (int argc, char *argv[])
  97. {
  98.  char *soundfile = NULL;
  99.  int removed, stay = FALSE;
  100.  struct MsgPort *port;
  101.  
  102. #if !DETACH
  103.  _Backstdout = Output();
  104. #endif
  105.  
  106.  port = FindPort (PORTNAME);
  107.  if (!port)
  108.  {
  109.    port = &myport;
  110.    stay = TRUE;
  111.  }
  112.  
  113.  if (_Backstdout && argc)
  114.  {
  115.    if (stay)
  116.      Write (_Backstdout, BANNER, sizeof(BANNER));
  117.  
  118.    if (argc > 2)
  119.      usage ();
  120.    else if (argc == 2)
  121.      if (argv[1][0] == '-' && argv[1][1] == 'q')
  122.      {
  123.        if (stay)
  124.          stay = FALSE;
  125.        else
  126.        {
  127.          Signal (port->mp_SigTask, 1L << port->mp_SigBit);
  128.          port = &myport;
  129.        }
  130.        Write (_Backstdout, REMOVING, sizeof(REMOVING));
  131.      }
  132.      else
  133.        soundfile = argv[1];
  134.  
  135.    if (stay)
  136.    {
  137.      if (!soundfile)
  138.        usage ();
  139.      if (!load (soundfile))
  140.      {
  141.        Write (_Backstdout, NOTLOAD, sizeof(NOTLOAD));
  142.        soundfile = NULL;
  143.      }
  144.    }
  145.  
  146. #if DETACH
  147.    Close (_Backstdout);
  148. #endif
  149.  }
  150.  
  151.  if (stay && soundfile)
  152.  {
  153.    /* create port */
  154.    myport.mp_Node.ln_Name = PORTNAME;
  155.    myport.mp_Node.ln_Pri = 0;
  156.    myport.mp_Node.ln_Type = NT_MSGPORT;
  157.    myport.mp_Flags = PA_SIGNAL;
  158.    myport.mp_SigBit = AllocSignal (-1);
  159.    myport.mp_SigTask = FindTask (NULL);
  160.    AddPort (&myport);
  161.    port = &myport;
  162.  }
  163.  else
  164.    goto final;
  165.  
  166.  IntuitionBase = OpenLibrary ("intuition.library", 0);
  167.  
  168.  handler = FindTask (NULL);
  169.  beepsig = AllocSignal (-1);
  170.  
  171.  Forbid ();
  172.  oldbeep = SetFunction (IntuitionBase, _LVODisplayBeep, mybeep);
  173.  Permit ();
  174.  
  175.  removed = FALSE;
  176.  do
  177.  {
  178.    ULONG sigmask = Wait ((1L << port->mp_SigBit)|
  179.                          (SIGBREAKF_CTRL_C)    |
  180.                          (1L << beepsig)    );
  181.  
  182.    if (sigmask & (1L << beepsig))
  183.    {
  184. #if DEBUG
  185.      printf ("beeep!!!\n");
  186. #endif
  187.      play ();
  188.    }
  189.  
  190.    if (sigmask & (1L << port->mp_SigBit)  ||  sigmask & SIGBREAKF_CTRL_C)
  191.    {
  192.      Forbid ();
  193.      {
  194.        BeepFunc pbeep = SetFunction (IntuitionBase, _LVODisplayBeep, oldbeep);
  195.  
  196.        if (pbeep != mybeep)
  197.        {
  198.          /*
  199.           *    Someone has interposed a handler after me. My handler can't be
  200.           *  removed: otherwise the system will crash after the other handler
  201.           *  removes itself.
  202.           */
  203.          (void) SetFunction (IntuitionBase, _LVODisplayBeep, pbeep);
  204.        }
  205.        else
  206.          removed = TRUE;
  207.      }
  208.      Permit();
  209.    }
  210.  } while (!removed);
  211.  
  212.  FreeSignal (beepsig);
  213.  
  214.  CloseLibrary (IntuitionBase);
  215.  
  216.  /* Delete port */
  217.  RemPort (port);
  218.  FreeSignal (port->mp_SigBit);
  219.  
  220.  unload ();
  221.  
  222. final:
  223.  exit (0);
  224. }
  225.